
/******************************************************************
 * Copyright @ 2024 Gim. All rights reserverd.
 * @file   src\memory\index.ts
 * @author Gim
 * @date   2024/01/24 18:30
 * @desc   Memory 命名空间用于管理本插件需要记住的东西。
 ******************************************************************/

import * as vscode from 'vscode';
import { apiTreeDataProvider } from '../ApiTreeDataProvider';
import { TornaDocItem, TornaModuleItem, TornaProjectItem, TornaSpaceItem } from '../types/type';
export namespace Memory {
  export interface IUser {
    url: string;
    username: string;
    password: string;
    token: string;
    type?: 'torna' | 'apifox'
  };
  export interface ISpace extends TornaSpaceItem {
    visitor: IUser;
  }
  export interface IProject extends TornaProjectItem {
    visitor: IUser;
  }
  export interface IModule extends TornaModuleItem {
    visitor: IUser;
  }
  export interface IDoc extends TornaDocItem {
    visitor: IUser
  };
  export let userTemplate: IUser = {
    url: '',
    username: '',
    password: '',
    token: '',
  };

  export type UserKey = string;
  export interface ListsMap {
    space: Map<string, ISpace[]>;
    project: Map<string, IProject[]>;
    module: Map<string, IModule[]>;
    doc: Map<string, IDoc[]>;
  };
  export const listsMap: ListsMap = {
    space: new Map<UserKey, ISpace[]>(),
    project: new Map<UserKey, IProject[]>(),
    module: new Map<UserKey, IModule[]>(),
    doc: new Map<UserKey, IDoc[]>(),
  };
  export const spaceLists = listsMap.space;
  export const projectLists = listsMap.project;
  export const moduleLists = listsMap.module;
  export const docLists = listsMap.doc;


  export let fullDocList: IDoc[] = [];
  export function userKey(user: IUser): UserKey {
    return `[${user.username}]${user.url}${user.type}`;
  }
  export function addSpaceList(user: IUser, list: TornaSpaceItem[]): Memory.ISpace[] {
    const ret = list.map(v => ({ ...v, visitor: user }));
    spaceLists.set(userKey(user), ret);
    apiTreeDataProvider.refresh();
    return ret;
  }
  export function removeSpaceList(user: IUser) {
    spaceLists.delete(userKey(user));
    apiTreeDataProvider.refresh();
  }
  export function addProjectList(user: IUser, list: TornaProjectItem[]): Memory.IProject[] {
    const ret = list.map(v => ({ ...v, visitor: user }));
    projectLists.set(userKey(user), ret);
    return ret;
  }


  /**
   * 删除指定用户在本地贮存的项目列表信息
   * @date 1/24/2024 - 6:28:46 PM
   *
   * @export
   * @param {IUser} user
   */
  export function removeProjectList(user: IUser) {
    projectLists.delete(userKey(user));
  }
  export function addModuleList(user: IUser, list: TornaModuleItem[]): Memory.IModule[] {
    const ret = list.map(v => ({ ...v, visitor: user }));
    moduleLists.set(userKey(user), ret);
    return ret;
  }


  /**
   * 删除指定用户在本地贮存的模块列表信息
   * @date 1/24/2024 - 6:28:17 PM
   *
   * @export
   * @param {IUser} user 指定用户
   */
  export function removeModuleList(user: IUser) {
    moduleLists.delete(userKey(user));
  }

  export function addDocList(user: IUser, list: TornaDocItem[]): Memory.IDoc[] {
    const ret = list.map(v => ({ ...v, visitor: user }));
    docLists.set(userKey(user), ret);
    _flatDocList();
    return ret;
  }

  /**
   * 删除指定用户在本地贮存的接口列表信息
   * @date 1/24/2024 - 6:27:22 PM
   *
   * @export
   * @param {IUser} user 指定用户
   */
  export function removeDocList(user: IUser) {
    docLists.delete(userKey(user));
    _flatDocList();
  }
  export function context(): vscode.ExtensionContext { return _context!; }
  export function init(context: vscode.ExtensionContext) { _context = context; }


  /**
   * 删除指定用户在本地的相关信息
   * @date 1/24/2024 - 6:26:10 PM
   *
   * @export
   * @param {IUser} user 指定用户
   */
  export function removeMemory(user: IUser) {
    removeDocList(user);
    removeSpaceList(user);
    removeModuleList(user);
    removeProjectList(user);
  }

  export function findSpace(user: IUser, id: string) {
    return spaceLists.get(userKey(user))?.find(v => v.id === id);
  }
  export function findProject(user: IUser, id: string) {
    return projectLists.get(userKey(user))?.find(v => v.id === id);
  }
  export function findModule(user: IUser, id: string) {
    return moduleLists.get(userKey(user))?.find(v => v.id === id);
  }
  export function findDoc(user: IUser, id: string) {
    return docLists.get(userKey(user))?.find(v => v.id === id);
  }

  type MapKey<M = any> = M extends Map<infer K, any> ? K : never;
  type MapValue<M = any> = M extends Map<any, infer V> ? V : never;
  type ArrayValue<A = any> = A extends Array<infer V> ? V : never;

  export function list<K extends keyof ListsMap>(type: K, user: IUser): MapValue<ListsMap[K]> | undefined {
    return listsMap[type].get(userKey(user)) as any;
  }
  export function find<K extends keyof ListsMap>(type: K, user: IUser, id: string): ArrayValue<MapValue<ListsMap[K]>> | undefined {
    return (list(type, user) as any)?.find((v: any) => v.id === id) as any;
  }

  function _flatDocList() {
    fullDocList.length = 0;
    docLists.forEach(l => fullDocList.push(...l));
  }
  let _context: vscode.ExtensionContext | undefined;
}